<?php
declare(strict_types=1);


namespace App\Game\Mapper;

use App\Fastapp\Model\Account;
use App\Fastapp\Model\AccountRecharge;
use App\Fastapp\Model\AccountWithdrawal;
use App\Game\Model\Game;
use App\Game\Model\GameBet;
use App\Game\Model\GameCategory;
use App\Game\Model\GameTag;
use Carbon\Carbon;
use Hyperf\Database\Model\Builder;
use Mine\Abstracts\AbstractMapper;

/**
 * 游戏列表Mapper类
 */
class GameMapper extends AbstractMapper
{
    /**
     * @var Game
     */
    public $model;

    public function assignModel()
    {
        $this->model = Game::class;
    }

    /**
     * 搜索处理器
     * @param Builder $query
     * @param array $params
     * @return Builder
     */
    public function handleSearch(Builder $query, array $params): Builder
    {
        // 标识
        if (isset($params['code']) && filled($params['code'])) {
            $query->where('code', '=', $params['code']);
        }

        // 平台
        if (isset($params['platform']) && filled($params['platform'])) {
            $query->where('platform', '=', $params['platform']);
        }

        // 供应商
        if (isset($params['provider']) && filled($params['provider'])) {
            $query->where('provider', '=', $params['provider']);
        }

        if (isset($params['type']) && filled($params['type'])) {
            $query->where('type', '=', $params['type']);
        }

        return $query->with(['category' => function ($query) {
            $query->with(['category:id,name']);
        }, 'tag' => function ($query) {
            $query->with(['tag:id,name']);
        }]);
    }

    public function getPageList(?array $params, bool $isScope = true, string $pageName = 'page'): array
    {
        $res = parent::getPageList($params, $isScope, $pageName);
        foreach ($res['items'] as $item) {
            $cates = $item->category->toArray();
            $tags = $item->tag->toArray();
            $item->cate_ids = array_column($cates, 'category_id');
            $item->tag_ids = array_column($tags, 'tag_id');
            $item->setHidden(['category']);
            $item->categorys = implode(',', $item->category->map(function ($item) {
                if ($item->category) return fastapp_lang_text($item->category->name);
                return '';
            })->toArray());
            $item->tags = implode(',', $item->tag->map(function ($item) {
                if ($item->tag) return fastapp_lang_text($item->tag->name);
                return '';
            })->toArray());
        }
        return $res;
    }

    public function update(mixed $id, array $data): bool
    {
        $s = parent::update($id, $data);
        if ($s) {
            GameCategory::query()->where(['game_id' => $id])->delete();
            GameTag::query()->where(['game_id' => $id])->delete();
            $this->extracted($data, $id);
        }
        return $s;
    }

    public function save(array $data): mixed
    {
        $id = parent::save($data);
        if ($id) {
            $this->extracted($data, $id);
        }
        return $id;
    }

    /**
     * @param array $data
     * @param mixed $id
     * @return void
     */
    public function extracted(array $data, mixed $id): void
    {
        $in = $in2 = [];
        foreach ($data['cate_ids'] ?? [] as $cate_id) {
            $in[] = [
                'category_id' => $cate_id,
                'game_id' => $id,
            ];
        }
        foreach ($data['tag_ids'] ?? [] as $tag_id) {
            $in2[] = [
                'tag_id' => $tag_id,
                'game_id' => $id,
            ];
        }
        if ($in) GameCategory::query()->insert($in);
        if ($in2) GameTag::query()->insert($in2);
    }

    public function statistics(): array
    {
        $btw = [Carbon::now()->subDay()->toDateString() . ' 00:00:00', date('Y-m-d') . ' 00:00:00'];
        return [
            'account_total' => Account::query()->count(),
            'account_today' => Account::query()->whereBetween('created_at', $btw)->count(),
            'bet_total' => nfmt(GameBet::query()->whereIn('status', [1, 2])->sum('amount')),
            'bet_today' => nfmt(GameBet::query()->whereIn('status', [1, 2])->whereBetween('created_at', $btw)->sum('amount')),
            'bet_kill' => nfmt(GameBet::query()->where(['status' => 2])->sum('amount')),
            'bet_pump' => GameBet::query()->sum('pump'),
            'recharge_total' => nfmt(AccountRecharge::query()->where(['status' => 1])->sum('amount')),
            'recharge_today' => nfmt(AccountRecharge::query()->where(['status' => 1])->whereBetween('created_at', $btw)->sum('amount')),
            'recharge_pump' => nfmt(AccountRecharge::query()->where(['status' => 1])->sum('pump')),
            'withdrawal_total' => nfmt(AccountWithdrawal::query()->where(['status' => 1])->sum('amount')),
            'withdrawal_today' => nfmt(AccountWithdrawal::query()->where(['status' => 1])->whereBetween('created_at', $btw)->sum('amount')),
            'withdrawal_pump' => nfmt(AccountWithdrawal::query()->where(['status' => 1])->sum('pump')),
        ];
    }
}